home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-04-21 | 14.8 KB | 404 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: FWArDyna.cpp
- // Release Version: $ 1.0d1 $
- //
- // Creation Date: 3/28/94
- //
- // Copyright: © 1994 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #ifndef FWARDYNA_H
- #include "FWArDyna.h"
- #endif
-
- #ifndef FWARSTRM_H
- #include "FWArStrm.h"
- #endif
-
- #ifndef FWOBJREG_H
- #include "FWObjReg.h"
- #endif
-
- #ifndef FWPRISTR_H
- #include "FWPriStr.h"
- #endif
-
- #ifndef FWPRITAS_H
- #include "FWPriTas.h"
- #endif
-
- #pragma segment FWArchiv
-
- //========================================================================================
- // Class FW_CDynamicArchiver
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::FW_CDynamicArchiver
- //----------------------------------------------------------------------------------------
-
- FW_CDynamicArchiver::FW_CDynamicArchiver(const char* classLabel,
- const char* className,
- FW_CDynamicArchiver::MapNameToLabel& localNameToLabelMap,
- FW_CDynamicArchiver::MapLabelToIOFunction& localLabelToIOFunctionMap,
- FW_CReadableArchive::InputFunction inputFunction,
- FW_CWritableArchive::OutputFunction outputFunction)
- {
- BC_Boolean bindOkay;
-
- bindOkay = localNameToLabelMap.Bind(FW_SPrivArcStr(className), FW_SPrivArcStr(classLabel));
- FW_ASSERT(bindOkay);
-
- bindOkay = localLabelToIOFunctionMap.Bind(FW_SPrivArcStr(classLabel), FW_SPrivArcFun(inputFunction, outputFunction));
- FW_ASSERT(bindOkay);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::FW_CDynamicArchiver
- //----------------------------------------------------------------------------------------
-
- FW_CDynamicArchiver::FW_CDynamicArchiver(const char* oldVersionClassLabel,
- FW_CDynamicArchiver::MapLabelToIOFunction& localLabelToIOFunctionMap,
- FW_CReadableArchive::InputFunction inputFunction)
- {
- BC_Boolean bindOkay = localLabelToIOFunctionMap.Bind(FW_SPrivArcStr(oldVersionClassLabel), FW_SPrivArcFun(inputFunction, 0));
- FW_ASSERT(bindOkay);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::InputObject
- //----------------------------------------------------------------------------------------
-
- void FW_CDynamicArchiver::InputObject(FW_CReadableArchive& readableArchive,
- void*& object)
- {
- FW_CReadableArchive::InputFunction inputFunction = (FW_CReadableArchive::InputFunction)readableArchive.InputObject(ReadClassLabel);
-
- object = readableArchive.InputObject(inputFunction);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::ReadClassLabel
- //
- // Notes:
- // 1. You may have expected this method to return a pointer to the class label. Doing
- // so, however, would result in two problems. First, the pointer returned would have
- // to be to a buffer allocated by this method and who would delete it? Second, even
- // if a pointer to a class label was returned, by returning an:
- // 'FW_CReadableArchive::InputFunction'
- // pointer, we only have to map a particular class label once (via the map
- // 'gMapClassLabelToObjectIOFunction') for the entire 'readableArchive'. That is,
- // if there are "n" occurrences of a particular class label in a 'readableArchive',
- // one reference to 'gMapClassLabelToObjectIOFunction' is made instead of "n".
- //----------------------------------------------------------------------------------------
-
- void* FW_CDynamicArchiver::ReadClassLabel(FW_CReadableArchive& readableArchive)
- {
- // Read the class label of the object from the archive.
- char classLabel[kMaxClassLabelLength];
- short labelLength;
- readableArchive >> labelLength;
- FW_ASSERT(labelLength < kMaxClassLabelLength);
- readableArchive.Read(classLabel, labelLength);
- classLabel[labelLength] = 0;
-
- // Look up the InputFunction in the map using the class label as the key.
- FW_ASSERT(GetMapLabelToIOFunction().IsBound(FW_SPrivArcStr(classLabel)));
- return GetMapLabelToIOFunction().ValueOf(FW_SPrivArcStr(classLabel))->fInputFunction;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::OutputObject
- //----------------------------------------------------------------------------------------
-
- void FW_CDynamicArchiver::OutputObject(FW_CWritableArchive& writableArchive,
- const void* object,
- const char* className)
- {
- // Use 'gMapClassNameToClassLabel' to map the 'className' to the class label.
- FW_ASSERT(GetMapNameToLabel().IsBound(FW_SPrivArcStr(className)));
- FW_SPrivArcStr label(*GetMapNameToLabel().ValueOf(FW_SPrivArcStr(className)));
-
- // Write the class label out to the archive.
- writableArchive.OutputObject(WriteClassLabel, label.fString);
-
- // Write the 'object' data out to the archive.
- FW_ASSERT(GetMapLabelToIOFunction().IsBound(label));
- writableArchive.OutputObject(GetMapLabelToIOFunction().ValueOf(label)->fOutputFunction, object);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::WriteClassLabel
- //----------------------------------------------------------------------------------------
-
- void FW_CDynamicArchiver::WriteClassLabel(FW_CWritableArchive& writableArchive,
- const void* classLabel)
- {
- short labelLength = FW_PrimitiveStringLength((const char *)classLabel);
- writableArchive << labelLength;
- writableArchive.Write(classLabel, labelLength);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::HashFunction
- //
- // The algorithm for the hash function is from:
- // Sedgewick, Robert, "Algorithms in C", Addison-Wesley, 1990, Page 233
- //
- // The constant '64' used in the algorithm is (according to Sedgewick) "... not
- // particularly important".
- //----------------------------------------------------------------------------------------
-
- BC_Index FW_CDynamicArchiver::HashFunction(const FW_SPrivArcStr& string)
- {
- const char* charPtr = string.fString;
- BC_Index hashValue = 0;
-
- while (*charPtr != '\0')
- {
- hashValue = ((64 * hashValue) + *charPtr) % kPrime;
- ++charPtr;
- }
-
- return hashValue;
- }
-
- #ifndef FW_HAS_INSTANCE_DATA
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::Initialize
- //----------------------------------------------------------------------------------------
-
- void FW_CDynamicArchiver::Initialize(FW_SPrivDynamicArchiverGlobals& globals)
- {
- globals.gMapClassNameToClassLabel = new MapNameToLabel(HashFunction);
- globals.gMapClassNameToClassLabel->SetChunkSize(kChunkSize);
-
- globals.gMapClassLabelToObjectIOFunction = new MapLabelToIOFunction(HashFunction);
- globals.gMapClassLabelToObjectIOFunction->SetChunkSize(kChunkSize);
- }
- #endif
-
- #ifndef FW_HAS_INSTANCE_DATA
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::Terminate
- //----------------------------------------------------------------------------------------
-
- void FW_CDynamicArchiver::Terminate()
- {
- FW_SPrivDynamicArchiverGlobals& globals = GetDynamicArchiverGlobals();
- delete globals.gMapClassNameToClassLabel;
- delete globals.gMapClassLabelToObjectIOFunction;
- }
- #endif
-
- #ifndef FW_HAS_INSTANCE_DATA
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::GetDynamicArchiverGlobals
- //----------------------------------------------------------------------------------------
-
- FW_SPrivDynamicArchiverGlobals& FW_CDynamicArchiver::GetDynamicArchiverGlobals()
- {
- FW_SPrivDynamicArchiverGlobals *globals = (FW_SPrivDynamicArchiverGlobals*)FW_CPrivTaskGlobals::GetTaskGlobals(kDynamicArchiverGlobalsOffset);
-
- if (globals->gMapClassNameToClassLabel == 0)
- Initialize(*globals);
- return *globals;
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::MapNameToLabel& FW_CDynamicArchiver::GetMapNameToLabel
- //----------------------------------------------------------------------------------------
-
- FW_CDynamicArchiver::MapNameToLabel& FW_CDynamicArchiver::GetMapNameToLabel()
- {
- #ifdef FW_HAS_INSTANCE_DATA
- return *gLocalMapClassNameToClassLabel;
- #else
- return *GetDynamicArchiverGlobals().gMapClassNameToClassLabel;
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::MapLabelToIOFunction& FW_CDynamicArchiver::GetMapLabelToIOFunction
- //----------------------------------------------------------------------------------------
-
- FW_CDynamicArchiver::MapLabelToIOFunction& FW_CDynamicArchiver::GetMapLabelToIOFunction()
- {
- #ifdef FW_HAS_INSTANCE_DATA
- return *gLocalMapClassLabelToObjectIOFunction;
- #else
- return *GetDynamicArchiverGlobals().gMapClassLabelToObjectIOFunction;
- #endif
- }
-
-
- //========================================================================================
- // Struct FW_SPrivArcStr
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_SPrivArcStr::FW_SPrivArcStr
- //----------------------------------------------------------------------------------------
-
- FW_SPrivArcStr::FW_SPrivArcStr() :
- fString(0)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_SPrivArcStr::FW_SPrivArcStr
- //----------------------------------------------------------------------------------------
-
- FW_SPrivArcStr::FW_SPrivArcStr(const FW_SPrivArcStr& string) :
- fString(string.fString)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_SPrivArcStr::FW_SPrivArcStr
- //----------------------------------------------------------------------------------------
-
- FW_SPrivArcStr::FW_SPrivArcStr(const char* string) :
- fString(string)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_SPrivArcStr::operator=
- //----------------------------------------------------------------------------------------
-
- FW_SPrivArcStr& FW_SPrivArcStr::operator=(const FW_SPrivArcStr& string)
- {
- fString = string.fString;
- return *this;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_SPrivArcStr::operator==
- //----------------------------------------------------------------------------------------
-
- BC_Boolean FW_SPrivArcStr::operator==(const FW_SPrivArcStr& string) const
- {
- return FW_PrimitiveStringEqual(fString, string.fString);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_SPrivArcStr::operator!=
- //----------------------------------------------------------------------------------------
-
- BC_Boolean FW_SPrivArcStr::operator!=(const FW_SPrivArcStr& string) const
- {
- return !operator==(string);
- }
-
-
- //========================================================================================
- // Struct FW_SPrivArcFun
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_SPrivArcFun::FW_SPrivArcFun
- //----------------------------------------------------------------------------------------
-
- FW_SPrivArcFun::FW_SPrivArcFun() :
- fInputFunction(0),
- fOutputFunction(0)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_SPrivArcFun::FW_SPrivArcFun
- //----------------------------------------------------------------------------------------
-
- FW_SPrivArcFun::FW_SPrivArcFun(const FW_SPrivArcFun& ioFunctions) :
- fInputFunction(ioFunctions.fInputFunction),
- fOutputFunction(ioFunctions.fOutputFunction)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_SPrivArcFun::FW_SPrivArcFun
- //----------------------------------------------------------------------------------------
-
- FW_SPrivArcFun::FW_SPrivArcFun(FW_CReadableArchive::InputFunction inputFunction,
- FW_CWritableArchive::OutputFunction outputFunction) :
- fInputFunction(inputFunction),
- fOutputFunction(outputFunction)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_SPrivArcFun& FW_SPrivArcFun::operator=
- //----------------------------------------------------------------------------------------
-
- FW_SPrivArcFun& FW_SPrivArcFun::operator=(const FW_SPrivArcFun& ioFunctions)
- {
- fInputFunction = ioFunctions.fInputFunction;
- fOutputFunction = ioFunctions.fOutputFunction;
- return *this;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_SPrivArcFun::operator==
- //----------------------------------------------------------------------------------------
-
- BC_Boolean FW_SPrivArcFun::operator==(const FW_SPrivArcFun& ioFunctions) const
- {
- return (fInputFunction == ioFunctions.fInputFunction) && (fOutputFunction == ioFunctions.fOutputFunction);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_SPrivArcFun::operator!=
- //----------------------------------------------------------------------------------------
-
- BC_Boolean FW_SPrivArcFun::operator!=(const FW_SPrivArcFun& ioFunctions) const
- {
- return !operator==(ioFunctions);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::MergeNameToLabelMaps
- //----------------------------------------------------------------------------------------
-
- void FW_CDynamicArchiver::MergeNameToLabelMaps(
- FW_CDynamicArchiver::MapNameToLabel& local,
- FW_CDynamicArchiver::MapNameToLabel& global)
- {
- BC_TMapActiveIterator<FW_SPrivArcStr, FW_SPrivArcStr> iterator(local);
- while (!iterator.IsDone())
- {
- BC_Boolean bindOkay;
- if (!global.IsBound(*iterator.CurrentItem()))
- {
- bindOkay = global.Bind(*iterator.CurrentItem(), *iterator.CurrentValue());
- FW_ASSERT(bindOkay);
- }
- iterator.Next();
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CDynamicArchiver::MergeLabelToIOFunctionMaps
- //----------------------------------------------------------------------------------------
-
- void FW_CDynamicArchiver::MergeLabelToIOFunctionMaps(
- FW_CDynamicArchiver::MapLabelToIOFunction& local,
- FW_CDynamicArchiver::MapLabelToIOFunction& global)
- {
- BC_TMapActiveIterator<FW_SPrivArcStr, FW_SPrivArcFun> iterator(local);
- while (!iterator.IsDone())
- {
- BC_Boolean bindOkay;
- if (!global.IsBound(*iterator.CurrentItem()))
- {
- bindOkay = global.Bind(*iterator.CurrentItem(), *iterator.CurrentValue());
- FW_ASSERT(bindOkay);
- }
- iterator.Next();
- }
- }
-
-